/*
 *  Copyright (C) 2010 Glauco
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.balisunrise.swing.commons;

import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;
import org.balisunrise.common.VisualEntityType;
import org.balisunrise.common.listeners.TransactionListener;
import org.balisunrise.common.Search;
import org.balisunrise.common.Editor;
import org.balisunrise.common.TransactionActions;
import org.balisunrise.common.abstracts.AbstractVisualEntity;
import org.balisunrise.common.events.TransactionModeChangedEvent;
import org.balisunrise.common.listeners.TransactionModeListener;
import org.balisunrise.swing.components.panel.TransactionPanel;

/**
 * Transação de uma entidade. Possui uma representação visual do tipo JPanel.
 *
 * @author Glauco
 * @see org.balisunrise.common.Transaction
 * @see javax.swing.JPanel
 */
public class Transaction extends AbstractVisualEntity implements
        org.balisunrise.common.Transaction<
            Search<?,?,?,JPanel>,
            Editor<?,?,?,JPanel>,
            TransactionActions<?,? extends VisualAction,JPanel>,
            TransactionPanel>,
        TransactionModeListener{

    public static final String PROP_EDITOR = "editor";
    public static final String PROP_SEARCH = "search";
    public static final String PROP_TRANSACTION_ACTIONS = "transactionActions";
    public static final String PROP_VISUAL_REPRESENTATION =
            "visualRepresentation";

    /**
     * Editor da Transação.
     */
    private Editor editor;

    /**
     * Busca da Transação.
     */
    private Search search;

    /**
     * Ações da transação.
     */
    private TransactionActions transactionActions;

    /**
     * Representação Visual da Transação.
     */
    private TransactionPanel visualRepresentation;

    /**
     * Listeners dos eventos da Transaction.
     */
    private List<TransactionListener> listeners;

    public Transaction() {
        listeners = new ArrayList<TransactionListener>();
    }

    /**
     * Atribui o editor.
     * @param editor
     */
    public void setEditor(Editor editor) {
        Editor old = this.editor;
        this.editor = editor;
        changeSupport.firePropertyChange(PROP_EDITOR, old, editor);
    }

    /**
     * Atribui a busca.
     * @param search
     */
    public void setSearch(Search search) {
        Search old = this.search;
        this.search = search;
        changeSupport.firePropertyChange(PROP_SEARCH, old, search);
    }

    /**
     * Atribui as ações da transação.
     * @param transactionActions
     */
    public void setTransactionActions(TransactionActions transactionActions) {

        TransactionActions old = this.transactionActions;

        if(this.transactionActions != null)
            this.transactionActions.removeModeChangedListener(this);

        this.transactionActions = transactionActions;
        this.transactionActions.addModeChangedListener(this);

        changeSupport.firePropertyChange(PROP_TRANSACTION_ACTIONS, old,
                transactionActions);
    }

    /**
     * Atribui a Representação Visual da Transação.
     * @param visualRepresentation
     */
    public void setVisualRepresentation(TransactionPanel visualRepresentation) {
        TransactionPanel old = this.visualRepresentation;
        this.visualRepresentation = visualRepresentation;
        changeSupport.firePropertyChange(PROP_VISUAL_REPRESENTATION, old,
                visualRepresentation);
    }

    /**
     * Retorna o objeto de Editor da Transaction.
     */
    @Override
    public Editor<?,?,?,JPanel> getEditor() {
        return editor;
    }

    /**
     * Retorna o objeto de Search da Transaction.
     */
    @Override
    public Search<?,?,?,JPanel> getSearch() {
        return search;
    }

    /**
     * Retorna o objeto de TransactionAction da Transaction
     */
    @Override
    public TransactionActions<?,? extends VisualAction,JPanel> getTransactionAction() {
        return transactionActions;
    }

    /**
     * Mostra a representação visual de Editor da Trasaction.
     */
    @Override
    public void showEditor() {
        editor.getMessenger().removeAllMessages();
        visualRepresentation.showEditor();
        editor.getEntityPanel().requestFocus();
    }

    /**
     * Mostra a representação visual de Search da Trasaction.
     */
    @Override
    public void showSearch() {
        visualRepresentation.showSearch();
        search.newSearch();
    }

    /**
     * Retorna a representação visual.
     */
    @Override
    public TransactionPanel getVisualRepresentation() {
        return visualRepresentation;
    }

    /**
     * Retorna o tipo do VisualEntity.<BR>
     * Sempre retornará TRANSACTION.
     * @return VisualEntityType.TRANSACTION;
     */
    @Override
    public final VisualEntityType getVisualEntityType() {
        return VisualEntityType.TRANSACTION;
    }

    @Override
    public void transactionModeChanged(TransactionModeChangedEvent evt) {
        if (editor == null)
            return ;
        if(editor.getMessenger() == null)
            return ;
        editor.getMessenger().setMode(evt.getMode());
    }

    @Override
    public void addTransactionListener(TransactionListener tl) {
        listeners.add(tl);
    }

    @Override
    public boolean removeTrasactionListener(TransactionListener tl) {
        return listeners.remove(tl);
    }

    @Override
    public TransactionListener[] getTransactionListeners() {
        return listeners.toArray(new TransactionListener[]{});
    }
}
